#include <iostream>
using namespace std;

class Solution {
public:
    int resolve(string s) {
        int n = (int)s.size();
        if (n == 0) return 0;
        int ans = 0;

        for (char x = 'a'; x <= 'z'; ++x) {
            for (char y = x + 1; y <= 'z'; ++y) {
                unordered_map<int,int> first;
                first.reserve(512);
                first[0] = -1;

                int pre = 0;
                int cntX = 0, cntY = 0;

                for (int i = 0; i < n; ++i) {
                    char c = s[i];
                    if (c != x && c != y) {
                        first.clear();
                        first[0] = i;
                        pre = 0;
                        cntX = cntY = 0;
                        continue;
                    }

                    if (c == x) { pre++; cntX++; }
                    else { pre--; cntY++; }

                    // 需要 pre[j]-pre[i]==±1 并且子串包含两种字母
                    if (first.count(pre - 1)) {
                        int len = i - first[pre - 1];
                        if (cntX > 0 && cntY > 0) ans = max(ans, len);
                    }
                    if (first.count(pre + 1)) {
                        int len = i - first[pre + 1];
                        if (cntX > 0 && cntY > 0) ans = max(ans, len);
                    }

                    if (!first.count(pre)) first[pre] = i;
                }
            }
        }
        return ans;
    }
};



class Solution2 {
public:
    // 返回最长“好名字”子串长度
    int resolve(string s) {
        int n = (int)s.size();
        if (n == 0) return 0;
        int ans = 0;

        for (char x = 'a'; x <= 'z'; ++x) {
            for (char y = x + 1; y <= 'z'; ++y) {  // 只枚举不同的两种字母
                unordered_map<int,int> first;     // 前缀和 -> 最早下标
                int pre = 0;                      // 当前前缀和
                first.reserve(512);
                first[0] = -1;                    // 空前缀位置

                for (int i = 0; i < n; ++i) {
                    char c = s[i];
                    if (c != x && c != y) {
                        // 片段被打断，重置
                        first.clear();
                        first[0] = -1;
                        pre = 0;
                        continue;
                    }
                    pre += (c == x ? 1 : -1);

                    // 需要 pre[j]-pre[i] == 1 或 == -1
                    if (first.count(pre - 1)) ans = max(ans, i - first[pre - 1]);
                    if (first.count(pre + 1)) ans = max(ans, i - first[pre + 1]);

                    if (!first.count(pre)) first[pre] = i; // 只保留最早出现的位置
                }
            }
        }
        return ans;
    }
};


class Solution3 {
public:
    bool judgePoints(vector<int>& cards, int points) {
        nums.assign(cards.begin(), cards.end());
        vis.clear();
        return dfs(nums, points);
    }

private:
    const double EPS = 1e-6;
    vector<double> nums;
    unordered_set<string> vis; // 记忆化：失败过的状态

    // 把当前数组做成 key（排序 + 保留6位）
    string makeKey(const vector<double>& v) {
        vector<long long> t; t.reserve(v.size());
        for (double x : v) t.push_back(llround(x * 1e6));
        sort(t.begin(), t.end());
        string k; k.reserve(t.size() * 12);
        for (auto z : t) { k += to_string(z); k += ','; }
        return k;
    }

    bool dfs(vector<double> nums, int target) {
        int n = nums.size();
        if (n == 1) return fabs(nums[0] - target) < EPS;

        // 记忆化剪枝（失败态）
        string key = makeKey(nums);
        if (vis.count(key)) return false;
        vis.insert(key);

        // 只枚举 i<j，避免镜像重复
        for (int i = 0; i < n; ++i) {
            for (int j = i + 1; j < n; ++j) {
                vector<double> next;
                next.reserve(n - 1);
                for (int k = 0; k < n; ++k) if (k != i && k != j) next.push_back(nums[k]);

                // 层内去重：同一对(i,j)产生的等价结果只试一次
                unordered_set<long long> seen; seen.reserve(16);

                auto try_push = [&](double v)->bool{
                    long long q = llround(v * 1e6);
                    if (seen.insert(q).second) {
                        next.push_back(v);
                        if (dfs(next, target)) return true;
                        next.pop_back();
                    }
                    return false;
                };

                double a = nums[i], b = nums[j];
                // 可交换运算：+、*
                if (try_push(a + b)) return true;
                if (try_push(a * b)) return true;
                // 不可交换运算：-、/
                if (try_push(a - b)) return true;
                if (try_push(b - a)) return true;
                if (fabs(b) > EPS && try_push(a / b)) return true;
                if (fabs(a) > EPS && try_push(b / a)) return true;
            }
        }
        return false;
    }

    // 你原来的 compute 可保留或删除（已内联到上面）
    vector<double> compute(double a, double b) { /* 不再需要 */ return {}; }
};

class Solution4 {
public:
    ListNode* rotateList(ListNode* head, int k) {
        if (!head || !head->next || k == 0) return head;

        // 1. 计算链表长度，并找到尾节点
        int n = 1;
        ListNode* tail = head;
        while (tail->next) {
            tail = tail->next;
            n++;
        }

        // 2. 取余数
        k = k % n;
        if (k == 0) return head;

        // 3. 找到新的尾节点
        int steps = n - k - 1;
        ListNode* newTail = head;
        for (int i = 0; i < steps; i++) {
            newTail = newTail->next;
        }

        // 4. 重新链接
        ListNode* newHead = newTail->next;
        newTail->next = nullptr;
        tail->next = head;

        return newHead;
    }
};